home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
198_02
/
termio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-21
|
19KB
|
731 lines
/*
* The functions in this file negotiate with the operating system for
* characters, and write characters in a barely buffered fashion on the display.
* All operating systems.
*/
#include <stdio.h>
#include "estruct.h"
#include "edef.h"
#if MSDOS & TURBO
#include <conio.h>
#endif
#if AMIGA
#define NEW 1006L
#define AMG_MAXBUF 1024L
static long terminal;
static char scrn_tmp[AMG_MAXBUF+1];
static long scrn_tmp_p = 0;
#endif
#if ST520 & MEGAMAX
#include <osbind.h>
int STscancode = 0;
#endif
#if VMS
#include <stsdef.h>
#include <ssdef.h>
#include <descrip.h>
#include <iodef.h>
#include <ttdef.h>
#include <tt2def.h>
#define EFN 0 /* Event flag */
char obuf[NOBUF]; /* Output buffer */
int nobuf; /* # of bytes in above */
char ibuf[NIBUF]; /* Input buffer */
int nibuf; /* # of bytes in above */
int ibufi; /* Read index */
int oldmode[3]; /* Old TTY mode bits */
int newmode[3]; /* New TTY mode bits */
short iochan; /* TTY I/O channel */
#endif
#if CPM
#include <bdos.h>
#endif
#if MSDOS & (LATTICE | MSC | TURBO | AZTEC | MWC86 | C86)
union REGS rg; /* cpu register for use of DOS calls */
int nxtchar = -1; /* character held from type ahead */
#endif
#if RAINBOW
#include "rainbow.h"
#endif
#if USG /* System V */
#include <signal.h>
#include <termio.h>
#include <fcntl.h>
struct termio otermio; /* original terminal characteristics */
struct termio ntermio; /* charactoristics to use inside */
#if MSC
/* #include <sgtty.h> */ /* not needed */
#undef FIOCLEX
#undef FIONCLEX
#include <sys/ioctl.h>
int tafd; /* extra fd opened with no wait */
int fcstat; /* saved fcntl status */
#define NIBUF 63
char ibuf[NIBUF]; /* Input buffer */
int nibuf = 0; /* # of bytes in above */
int ibufi = 0; /* Read index */
#else
int kbdflgs; /* saved keyboard fd flags */
int kbdpoll; /* in O_NDELAY mode */
int kbdqp; /* there is a char in kbdq */
char kbdq; /* char we've already read */
#endif
#endif
#if V7 | BSD
#undef CTRL
#include <sgtty.h> /* for stty/gtty functions */
#include <signal.h>
struct sgttyb ostate; /* saved tty state */
struct sgttyb nstate; /* values for editor mode */
struct tchars otchars; /* Saved terminal special character set */
struct tchars ntchars = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#endif
/* A lot of nothing */
#if BSD
#include <sys/ioctl.h> /* to get at the typeahead */
extern int rtfrmshell(); /* return from suspended shell */
#if BSD29
#else
#define TBUFSIZ 128
char tobuf[TBUFSIZ]; /* terminal output buffer */
#endif
#endif
extern int termflag;
/*
* This function is called once to set up the terminal device streams.
* On VMS, it translates TT until it finds the terminal, then assigns
* a channel to it and sets it raw. On CPM it is a no-op.
*/
ttopen()
{
#if AMIGA
char oline[NSTRING];
#if AZTEC
extern Enable_Abort; /* Turn off ctrl-C interrupt */
Enable_Abort = 0; /* for the Manx compiler */
#endif
strcpy(oline, "RAW:0/0/640/200/");
strcat(oline, PROGNAME);
strcat(oline, " ");
strcat(oline, VERSION);
strcat(oline, "/Amiga");
terminal = Open(oline, NEW);
#endif
#if VMS
struct dsc$descriptor idsc;
struct dsc$descriptor odsc;
char oname[40];
int iosb[2];
int status;
odsc.dsc$a_pointer = "TT";
odsc.dsc$w_length = strlen(odsc.dsc$a_pointer);
odsc.dsc$b_dtype = DSC$K_DTYPE_T;
odsc.dsc$b_class = DSC$K_CLASS_S;
idsc.dsc$b_dtype = DSC$K_DTYPE_T;
idsc.dsc$b_class = DSC$K_CLASS_S;
do {
idsc.dsc$a_pointer = odsc.dsc$a_pointer;
idsc.dsc$w_length = odsc.dsc$w_length;
odsc.dsc$a_pointer = &oname[0];
odsc.dsc$w_length = sizeof(oname);
status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
exit(status);
if (oname[0] == 0x1B) {
odsc.dsc$a_pointer += 4;
odsc.dsc$w_length -= 4;
}
} while (status == SS$_NORMAL);
status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
if (status != SS$_NORMAL)
exit(status);
/* sense mode returns:
* mode[0] :0-7 = class, :8-15 = type, :16-31 = width
* mode[1] :0-23 = characteristics, :24-31 = length
*/
status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
oldmode, sizeof(oldmode), 0, 0, 0, 0);
if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
exit(status);
newmode[0] = oldmode[0];
newmode[1] = oldmode[1] /* | TT$M_NOECHO */ ;
newmode[2] = oldmode[2];
if (!termflag) {
newmode[1] &= ~(TT$M_TTSYNC|TT$M_HOSTSYNC);
newmode[2] |= TT2$M_PASTHRU;
}
status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
newmode, sizeof(newmode), 0, 0, 0, 0);
if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
exit(status);
term.t_nrow = (newmode[1]>>24) - 1;
if (term.t_nrow > term.t_mrow) term.t_mrow = term.t_nrow;
term.t_ncol = newmode[0]>>16;
if (term.t_ncol > term.t_mcol) term.t_mcol = term.t_ncol;
#endif
#if CPM
#endif
#if MSDOS & (HP150 == 0) & LATTICE
/* kill the ctrl-break interupt */
rg.h.ah = 0x33; /* control-break check dos call */
rg.h.al = 1; /* set the current state */
rg.h.dl = 0; /* set it OFF */
intdos(&rg, &rg); /* go for it! */
#endif
#if USG
ioctl(0, TCGETA, &otermio); /* save old settings */
ntermio.c_oflag = 0; /* setup new settings */
if (termflag)
ntermio.c_iflag = otermio.c_iflag & (IXON|IXANY|IXOFF);
else
ntermio.c_iflag = 0;
ntermio.c_cflag = otermio.c_cflag;
ntermio.c_lflag = 0;
ntermio.c_line = otermio.c_line;
ntermio.c_cc[VMIN] = 1;
ntermio.c_cc[VTIME] = 0;
ioctl(0, TCSETAW, &ntermio); /* and activate them */
#ifdef TCXONC
/* ioctl(0, TCXONC, 1); */ /* restart suspended (^S'ed) output */
#endif
#if MSC
tafd = open("/dev/tty", O_RDONLY, 0);
ioctl(tafd, TCSETA, &ntermio); /* and activate them */
fcstat = fcntl(tafd, F_GETFL, 0);
fcntl(tafd, F_SETFL, fcstat | O_NDELAY);
#else
kbdflgs = fcntl( 0, F_GETFL, 0 );
kbdpoll = FALSE;
#endif
#endif
#if V7 | BSD
gtty(0, &ostate); /* save old state */
gtty(0, &nstate); /* get base of new state */
nstate.sg_flags |= RAW;
nstate.sg_flags &= ~(ECHO|CRMOD); /* no echo for now... */
stty(0, &nstate); /* set mode */
ioctl(0, TIOCGETC, &otchars); /* Save old characters */
ioctl(0, TIOCSETC, &ntchars); /* Place new character into K */
#endif
#if BSD
#if BSD29
#else
/* provide a smaller terminal output buffer so that
the type ahead detection works better (more often) */
setbuffer(stdout, &tobuf[0], TBUFSIZ);
#ifdef _IONBF
setvbuf(stdin, NULL, _IONBF, 0);
#endif
#endif
signal(SIGTSTP,SIG_DFL); /* set signals so that we can */
signal(SIGCONT,rtfrmshell); /* suspend & restart emacs */
#endif
/* on all screens we are not sure of the initial position
of the cursor */
ttrow = 999;
ttcol = 999;
}
/*
* This function gets called just before we go back home to the command
* interpreter. On VMS it puts the terminal back in a reasonable state.
* Another no-operation on CPM.
*/
ttclose()
{
#if AMIG